package com.reload.reaactor;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @Date: 2024/12/7 - 15:14
 * @Version: 17
 * @Author: Reloading
 * @Description: 错误处理
 */
public class ErrorHandle {
    public static void main(String[] args) {
        // 捕获并返回一个静态值
        returnStaticValue();

        // 捕获并动态计算一个返回值
        returnDynamicsValue();

        // 自定义异常
        customizeError();

        // 捕获异常，记录特殊的错误日志，重新抛出
        catchAndLog();

        // 无论流正常还是异常结束，都会执行
        doFinally();

        // 忽略错误，继续执行
        ignoreError();
    }

    private static void ignoreError() {
        Flux.just(1, 2, 3, 0, 5)
                .map(i -> 10 / i)
                // 错误后停止流
                // .onErrorStop()
                // 将错误结束信号转为正常结束信号
                // .onErrorComplete()
                .onErrorContinue((err, val) -> {
                    System.out.println("err = " + err);
                    System.out.println("val = " + val);
                    System.out.println("发现" + val + "有问题了，继续执行其他的，我会记录这个问题");
                }) // 发生
                .subscribe(v -> System.out.println("v = " + v),
                        err -> System.out.println("err = " + err));
    }

    private static void doFinally() {
        Flux.just(1, 2, 3, 4)
                .map(i -> "100 / " + i + " = " + (100 / i))
                .doOnError(err -> {
                    System.out.println("发布者 - err已被记录 = " + err);
                })
                .doFinally(signalType -> {
                    System.out.println("发布者 - 流信号：" + signalType);
                });
    }

    private static void catchAndLog() {
        Flux.just(1, 2, 0, 4)
                .map(i -> "100 / " + i + " = " + (100 / i))
                .doOnError(err -> {
                    System.out.println("发布者 - err已被记录 = " + err);
                }).subscribe(v -> System.out.println("v = " + v),
                        err -> System.out.println("消费者 err = " + err),
                        () -> System.out.println("流结束"));
    }

    private static void customizeError() {
        Flux.just(1, 2, 0, 4)
                .map(i -> "100 / " + i + " = " + (100 / i))
                .onErrorMap(err -> new BusinessException(err.getMessage() + ": 又炸了..."))
                .subscribe(v -> System.out.println("v = " + v),
                        err -> System.out.println("消费者 err = " + err),
                        () -> System.out.println("流结束"));
    }

    private static void returnDynamicsValue() {
        Flux.just(1, 2, 0, 4)
                .map(i -> "100 / " + i + " = " + (100 / i))
                // 捕获并动态计算一个返回值
                .onErrorResume(err -> hahaha(err))
                .subscribe(v -> System.out.println("v = " + v),
                        err -> System.out.println("消费者 err = " + err),
                        () -> System.out.println("流结束"));
    }

    // 默认情况
    private static void returnStaticValue() {
        Flux.just(1, 2, 0, 4)
                .map(i -> "100 / " + i + " = " + (100 / i))
                // 发生错误返回默认的值 消费者无异常感知
                // .onErrorReturn("哈哈-6666")
                // 效果：吃掉异常、消费者无异常感知，返回一个默认值，流正常完成
                .onErrorReturn(ArithmeticException.class, "哈哈-6666")
                .subscribe(v -> System.out.println("v = " + v),
                        err -> System.out.println("消费者 err = " + err),
                        () -> System.out.println("流结束"));
    }


    static Mono<String> hahaha(Throwable throwable) {
        if (throwable.getClass() == NullPointerException.class) {

        }
        return Mono.just("哈哈-" + throwable.getMessage());
    }

    // 自定义异常
    static class BusinessException extends RuntimeException {
        public BusinessException(String msg) {
            super(msg);
        }
    }
}
